/*************************************************************************
 *
 *  Copyright (C) 2013 Florian Dang <florian.coin@gmail.com>
 *
 *  This file is part of NatusVerse.
 *
 *  NatusVerse is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  NatusVerse is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with NatusVerse.  If not, see <http://www.gnu.org/licenses/>.
 *
 *************************************************************************/

#ifndef INC_RAYTRACER_OBJECTS_SPHERE_H_
#define INC_RAYTRACER_OBJECTS_SPHERE_H_

/*!
 * \file        sphere.h
 * \brief       Sphere object
 * \author      Florian Dang
 * \date        2013
 */
 
#include "raytracer/objects/object.h"
#include "raytracer/objects/point.h"
#include "raytracer/objects/ray.h"

namespace raytracer
{
//! Sphere (object subclass)
/*!
  Define a sphere
*/
class Sphere : public Object
{
	public:
		//! sphere default constructor
		Sphere() {}

		//! sphere classic constructor
		Sphere(Material mat0, Point center0, int radius0)
			: Object(mat0), center_(center0), radius_(radius0) {}

		//! sphere destructor
		virtual ~Sphere() {}

		// Sphere(const Sphere& sphere)
		// 	: Object(sphere), center_(sphere.center()), radius_(sphere.radius()) {}

		virtual Sphere* clone() const // clone copying cf http://stackoverflow.com/questions/5880376/creating-a-clone-of-an-abstract-class
		{
			return new Sphere (* this);
		}

		//! center accessor
		inline const Point& center() const { return center_; }

		//! radius accessor
		inline const float& radius() const { return radius_; }

		//! sphere intersection
		/*!
			Radius : P = O + t*u
			Sphere : CP = r
		*/
		virtual bool Intersect(const Ray& ray, float& t) const;

		//! return normal vector at intersection
		virtual Vector Normal(const Point& intersection) const;

		//! display sphere informations on console
		virtual void Print() const;

		virtual void Move(float dx, float dy, float dz)
		{
			center_.set(center_.x() + dx, center_.y() + dy, center_.z() + dz);
		}

	private:
		Point center_; /*!< sphere center */
		float radius_; /*!< sphere radius */
};
}


#endif  // INC_RAYTRACER_OBJECTS_SPHERE_H_
